#include "ModbusHelper.h"
#include <QDebug>
#include <cmath>
#include <cstring>

// 将 2 个 16 位寄存器转换为 FLOAT32（大端字节序）
float ModbusHelper::registersToFloat(const QVector<quint16> &registers, int startIndex)
{
    // 验证寄存器数量
    if (!validateRegisters(registers, startIndex + 2))
    {
        qWarning() << "寄存器数量不足，无法转换为 FLOAT32";
        return 0.0f;
    }

    // 获取两个寄存器的值（Modbus TCP 使用大端字节序）
    quint16 highWord = registers[startIndex];    // 高字在前
    quint16 lowWord = registers[startIndex + 1]; // 低字在后

    // 组合为 32 位整数（大端模式）
    quint32 combined = (static_cast<quint32>(highWord) << 16) | lowWord;

    // 将 32 位整数重新解释为浮点数
    float result;
    std::memcpy(&result, &combined, sizeof(float));

    return result;
}

// 将 FLOAT32 转换为 2 个 16 位寄存器（大端字节序）
QVector<quint16> ModbusHelper::floatToRegisters(float value)
{
    QVector<quint16> registers(2);

    // 将浮点数转换为 32 位整数
    quint32 combined;
    std::memcpy(&combined, &value, sizeof(float));

    // 拆分为两个 16 位寄存器（大端模式：高字在前）
    registers[0] = static_cast<quint16>(combined >> 16);    // 高字
    registers[1] = static_cast<quint16>(combined & 0xFFFF); // 低字

    return registers;
}

// 解析温度数据
float ModbusHelper::parseTemperature(const QVector<quint16> &registers, int startIndex)
{
    float temperature = registersToFloat(registers, startIndex);

    if (!isValidFloat(temperature))
    {
        qWarning() << "温度数据无效:" << temperature;
        return 0.0f;
    }

    // 温度合理性检查（-50℃ ~ 200℃）
    if (temperature < -50.0f || temperature > 200.0f)
    {
        qWarning() << "温度数据超出合理范围:" << temperature << "℃";
    }

    return temperature;
}

// 解析压力数据
float ModbusHelper::parsePressure(const QVector<quint16> &registers, int startIndex)
{
    float pressure = registersToFloat(registers, startIndex);

    if (!isValidFloat(pressure))
    {
        qWarning() << "压力数据无效:" << pressure;
        return 0.0f;
    }

    // 压力合理性检查（0 ~ 10000 kPa）
    if (pressure < 0.0f || pressure > 10000.0f)
    {
        qWarning() << "压力数据超出合理范围:" << pressure << "kPa";
    }

    return pressure;
}

// 解析流量数据
float ModbusHelper::parseFlow(const QVector<quint16> &registers, int startIndex)
{
    float flow = registersToFloat(registers, startIndex);

    if (!isValidFloat(flow))
    {
        qWarning() << "流量数据无效:" << flow;
        return 0.0f;
    }

    // 流量合理性检查（0 ~ 1000 L/min）
    if (flow < 0.0f || flow > 1000.0f)
    {
        qWarning() << "流量数据超出合理范围:" << flow << "L/min";
    }

    return flow;
}

// 验证寄存器数据是否有效
bool ModbusHelper::validateRegisters(const QVector<quint16> &registers, int requiredCount)
{
    if (registers.isEmpty())
    {
        qWarning() << "寄存器数组为空";
        return false;
    }

    if (registers.size() < requiredCount)
    {
        qWarning() << "寄存器数量不足，需要" << requiredCount << "个，实际" << registers.size() << "个";
        return false;
    }

    return true;
}

// 检查浮点数是否有效
bool ModbusHelper::isValidFloat(float value)
{
    // 检查是否为 NaN 或 Inf
    if (std::isnan(value))
    {
        qWarning() << "浮点数为 NaN";
        return false;
    }

    if (std::isinf(value))
    {
        qWarning() << "浮点数为 Inf";
        return false;
    }

    return true;
}

// 将寄存器数据转换为十六进制字符串
QString ModbusHelper::registersToHexString(const QVector<quint16> &registers)
{
    QString hexString;
    for (int i = 0; i < registers.size(); ++i)
    {
        hexString += QString("0x%1").arg(registers[i], 4, 16, QChar('0')).toUpper();
        if (i < registers.size() - 1)
        {
            hexString += " ";
        }
    }
    return hexString;
}